<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>JS 代码的函数执行过程以及变量环境. 变量记录 | TBlog</title>
    <meta name="description" content="TBlog with vitePress">
    <link rel="stylesheet" href="/interview/assets/style.9156a4ed.css">
    <link rel="modulepreload" href="/interview/assets/Home.b86443e2.js">
    <link rel="modulepreload" href="/interview/assets/app.49accf37.js">
    <link rel="modulepreload" href="/interview/assets/Javascript_index.md.d996a3fc.lean.js">
    <link rel="modulepreload" href="/interview/assets/app.49accf37.js">
    <link rel="icon" href="/favicon.ico">
    <meta name="twitter:title" content="JS 代码的函数执行过程以及变量环境. 变量记录 | TBlog">
    <meta property="og:title" content="JS 代码的函数执行过程以及变量环境. 变量记录 | TBlog">
  </head>
  <body>
    <div id="app"><!--[--><div class="theme"><header class="nav-bar" data-v-7161a24b><div class="sidebar-button" data-v-7161a24b><svg class="icon" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z" class></path></svg></div><a class="nav-bar-title" href="/interview/" aria-label="TBlog, back to home" data-v-7161a24b data-v-4a583abe><!----> TBlog</a><div class="flex-grow" data-v-7161a24b></div><div class="nav" data-v-7161a24b><nav class="nav-links" data-v-7161a24b data-v-15acbf05><!--[--><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:66" target="_blank" rel="noopener noreferrer" data-v-641633f9>Music <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:80" target="_blank" rel="noopener noreferrer" data-v-641633f9>CMC <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://juejin.cn/user/2163479676978734/posts" target="_blank" rel="noopener noreferrer" data-v-641633f9>掘金 <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://gitee.com/tu_zhiwei98" target="_blank" rel="noopener noreferrer" data-v-641633f9>Gitee <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><!--]--><!----><!----></nav></div><!--[--><!--]--></header><aside class="sidebar" data-v-6b49cdcd><nav class="nav-links nav" data-v-6b49cdcd data-v-15acbf05><!--[--><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:66" target="_blank" rel="noopener noreferrer" data-v-641633f9>Music <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="http://101.43.7.188:80" target="_blank" rel="noopener noreferrer" data-v-641633f9>CMC <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://juejin.cn/user/2163479676978734/posts" target="_blank" rel="noopener noreferrer" data-v-641633f9>掘金 <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><div class="item" data-v-15acbf05><div class="nav-link" data-v-15acbf05 data-v-641633f9><a class="item isExternal" href="https://gitee.com/tu_zhiwei98" target="_blank" rel="noopener noreferrer" data-v-641633f9>Gitee <svg class="icon outbound" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewbox="0 0 100 100" width="15" height="15" data-v-641633f9><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path><polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div></div><!--]--><!----><!----></nav><!--[--><!--]--><ul class="sidebar-links" data-v-6b49cdcd><!--[--><li class="sidebar-link"><p class="sidebar-link-item">Vue3.2X</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/">基本语法&amp;使用</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/VueX">VueX4.x</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/Router">Router4.x</a><!----></li><li class="sidebar-link"><p class="sidebar-link-item">部分源码解析</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/reactive">响应式系统</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/source/Watch">Watch</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vue/source/nextTick">nextTick</a><!----></li></ul></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">WebPack</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/">基础配置</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/optimize">优化方案</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/common">常见的Loader以及Plugin</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/custom">自定义Loader以及Plugin</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/WebPack/advanced">手写简单的MY_Webpack</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">Javascript</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item active" href="/interview/Javascript/">基本语法</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#js-代码的函数执行过程以及变量环境-变量记录">JS 代码的函数执行过程以及变量环境. 变量记录</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#变量的查找规则">变量的查找规则</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#变量环境-变量记录">变量环境, 变量记录</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#js-的内存管理以及垃圾回收">**JS 的内存管理以及垃圾回收</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#js-的内存管理">JS 的内存管理</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#js-的垃圾回收">JS 的垃圾回收</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#常见的-gc-的算法">常见的 GC 的算法</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#this-指向">This 指向</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#this-面试题">this 面试题</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#实现-call-apply-bind-方法">实现 call .apply, bind 方法</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#原型以及原型链">原型以及原型链</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#隐式原型属性的作用">隐式原型属性的作用</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#函数也是一个对象-也是一个函数">函数也是一个对象, 也是一个函数</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#函数的-proto-属性">函数的 --proto-- 属性</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#判断原型的一些方法">判断原型的一些方法</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#对象-函数-原型-的关系">对象- 函数 原型 的关系</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#原型继承">原型继承</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#将-子类的原型指向-父类的原型">将 子类的原型指向 父类的原型</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#原型式-继承">原型式 -- 继承</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#寄生组合式继承">寄生组合式继承</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#闭包">闭包</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#闭包的定义">闭包的定义</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#闭包的访问过程">闭包的访问过程</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#es6-知识">ES6 知识</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#let-const-以及-作用域提升">let const 以及 作用域提升</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#三个不同的作用域">三个不同的作用域</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#symbol">symbol</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#set-weakmap-与-map">Set / WeakMap 与 Map</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#map">Map</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#es7">ES7</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#es8">ES8</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#es10">ES10</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#es-11">ES 11</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#es12">ES12</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#promise">Promise</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#promise-的基本使用-：是一个类-是一种规范机制-来保证设计异步">promise 的基本使用 ：是一个类 是一种规范机制 来保证设计异步</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#promise-状态">promise 状态</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#resolve-（参数）">resolve （参数）</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#then-方法-对象的方法，需要创建-promise-实例-放在-promise-的原型上的，-promise-ptototype-then-上">then 方法 对象的方法，需要创建 promise 实例 放在 Promise 的原型上的， Promise. ptototype.then 上</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#catch（）错误异常-拒绝捕获">Catch（）错误异常/拒绝捕获</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#promise-finally（es8）">promise finally（ES8）</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#promise-类方法">promise 类方法</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#iterator-迭代器-与-generator-生成器">iterator 迭代器 与 generator 生成器</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#迭代器协议：">迭代器协议：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#可迭代对象：">可迭代对象：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#原生迭代器对象">原生迭代器对象</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#可迭代对象的应用">可迭代对象的应用</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#生成器：">生成器：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#生成器的应用">生成器的应用</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#async-await">async/await</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#async-异步-关键字-声明一个函数为异步函数">async 异步 关键字 声明一个函数为异步函数</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#await">await</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#js-模块化">JS 模块化</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#commonjs">CommonJS</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#导出方案：">导出方案：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#导入方案：">导入方案：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#内部原理：">内部原理：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#模块的加载过程：">模块的加载过程：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#缺点：">缺点：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#es-module">ES Module</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#导出的方式：-具名导出">导出的方式： 具名导出</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#导入的方式：">导入的方式：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#导入导出结合使用：">导入导出结合使用：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#默认导出：">默认导出：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#import-异步加载-函数">import 异步加载 函数</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#import-meta-属性：">import.meta 属性：</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#es-module-的解析流程：">ES module 的解析流程：</a><!----></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="#进程-与线程">进程 与线程</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#事件循环-事件队列">事件循环/ 事件队列</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#宏任务队列-macrotask">宏任务队列(MacroTask)</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#微任务队列-microtask">微任务队列(MicroTask)</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#队列任务执行优先级">队列任务执行优先级</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#js-中的高阶函数">JS 中的高阶函数</a><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="#_1-map">1.map</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_2-filter">2.filter</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_3-foreach">3.forEach</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_4-sort">4.sort</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_5-some">5.some</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_6-every">6.every</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_7-reduce">7.reduce</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_8-reduceright">8.reduceRight</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_9-find">9.find</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#_10-findindex">10.findIndex</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="#链式调用高阶函数">链式调用高阶函数</a><!----></li></ul></li></ul></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Javascript/advanced">高级语法</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">TypeScript</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/TypeScript/">基本语法</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/TypeScript/combat">业务实战</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/TypeScript/advanced">高阶使用</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">浏览器相关</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Browser/">基本原理</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Browser/plugin">浏览器插件</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Browser/advanced">深入原理</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">计算机网络</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Network/">计算机网络</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Network/security">前端安全</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">HTML/CSS</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/CSS/">CSS</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/HTML/">HTML</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">Vite2.X</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vite/">基础配置</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Vite/optimize">原理以及优化</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">Node</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Node/">基本知识</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Node/pit">踩坑记录</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">其他前端工具</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Git/">Git</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Jenkins/">Jenkins</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/npm/">包管理工具</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">踩坑记录以及经验</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Pit/">踩坑</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/solution/">一些解决方案</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">面经</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Interview/">xxx面试</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Interview/two">xxX面试</a><!----></li></ul></li><li class="sidebar-link"><p class="sidebar-link-item">个人学习历程</p><ul class="sidebar-links"><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Myself/">个人情况说明</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Myself/pre">入行工作前</a><!----></li><li class="sidebar-link"><a class="sidebar-link-item" href="/interview/Myself/one">工作第一年</a><!----></li></ul></li><!--]--></ul><!--[--><!--]--></aside><!-- TODO: make this button accessible --><div class="sidebar-mask"></div><main class="page" data-v-7eddb2c4><div class="container" data-v-7eddb2c4><!--[--><!--]--><div style="position:relative;" class="content" data-v-7eddb2c4><div><h2 id="js-代码的函数执行过程以及变量环境-变量记录"><a class="header-anchor" href="#js-代码的函数执行过程以及变量环境-变量记录" aria-hidden="true">#</a> JS 代码的函数执行过程以及变量环境. 变量记录</h2><ol><li><p>当代码被解析,V8 引擎内部会自动创建一个全局对象(GlobalObject ==&gt; GO) , 有一些全局的对象,window:this 指向自己</p><p>​ GO: 中会把属性先将 var 声明的属性 name: undefined</p><p>​ 当在解析的时候 遇到了全局的函数声明 ,会开辟一块空间存储 声明的函数 (有一个内存地址 0X001) 在 GO: 中 foo: 0X001</p><p>​ 包含:: 父级作用域, 函数的执行体,</p></li><li><p>然后开始运行代码</p><ol><li>v8 为了执行代码,内部会有一个执行上下文栈(ECStack) ,函数调用栈</li><li>当我们执行全局代码的时候,需要创建 全局执行上下文(GEC) 全局代码需要执行的时候才会创建,并且放入 ECStack 中</li><li>如果是执行函数 例如 foo() . 会先创建一个 AO(activation object)对象,里面保存着函数内部变量的声明 ,然后会在 ECStck 中 开启 FEC(function execution context ) 函数执行上下文中 ,这个 FEC 中也包含 AO 对象 以及 scope chain AO + GO</li></ol></li></ol><img src="/interview/assets/js函数执行过程.e456f780.png" style="zoom:80%;"><p>​ 当函数执行完, 函数的执行上下文 FEC 会弹出栈, 会被销毁, 该函数多对应的 AO 如果没有被引用, 也会被销毁掉</p><h3 id="变量的查找规则"><a class="header-anchor" href="#变量的查找规则" aria-hidden="true">#</a> 变量的查找规则</h3><p>查找的顺序:</p><ol><li>沿着作用域链 查找 scope chain 由当前的 AO -&gt; GO 往上查找 (函数的作用域链 在编译的时候就被确定了) <strong>跟在哪里调用没有关系</strong></li></ol><h3 id="变量环境-变量记录"><a class="header-anchor" href="#变量环境-变量记录" aria-hidden="true">#</a> 变量环境, 变量记录</h3><p>GO, AO 这些 都是 ES5 之前的版本规范</p><p>ES6 之前:</p><p>​ 每一个执行上下文会被关联到一个变量环境 VO(variable object) ,在源代码中的变量和函数会被作为属性添加到 VO 中, 对于函数来说,参数也会被添加到 VO 中</p><p>ES6 之后</p><p>​ 每一个执行上下文会被关联到一个变量环境,(VariableEnvironment)中, 在执行代码中变量和函数的声明会作为环境记录(Environment)添加到变量环境中,对于函数来说,参数也会被作为环境记录添加到变量环境中</p><h2 id="js-的内存管理以及垃圾回收"><a class="header-anchor" href="#js-的内存管理以及垃圾回收" aria-hidden="true">#</a> **JS 的内存管理以及垃圾回收</h2><p><strong>不管什么样的编程语言，在代码的执行过程中都是需要给它分配内存的，不同的是某些编程语言需要我们自己手动的管理内存，某些编程语言会可以自动帮助我们管理内存：**</strong></p><p>不管以什么样的方式来管理内存，<strong>内存的管理都会有如下的生命周期</strong>：</p><ol><li>分配申请你需要的内存（申请）；</li><li>使用分配的内存（存放一些东西，比如对象等）；</li><li>不需要使用时，对其进行释放；</li></ol><p><strong>不同的编程语言对于第一步和第三步会有不同的实现：</strong></p><p>手动管理内存：比如 C、C++，包括早期的 OC，都是需要手动来管理内存的申请和释放的（malloc 和 free 函数）；</p><p>自动管理内存：比如 Java、JavaScript、Python、Swift、Dart 等，它们有自动帮助我们管理内存；</p><p>我们可以知道 JavaScript 通常情况下是不需要手动来管理的。</p><h3 id="js-的内存管理"><a class="header-anchor" href="#js-的内存管理" aria-hidden="true">#</a> <strong>JS 的内存管理</strong></h3><p>JavaScript 会在<strong>定义变量时</strong>为我们分配内存</p><p>基本数据类型 内存的分配会在执行时，直接在<strong>栈空间</strong>进行分配；</p><p>复杂数据类型 内存的分配会在<strong>堆内存</strong>中开辟一块空间，并且将这块空间的指针返回值变量引用</p><h3 id="js-的垃圾回收"><a class="header-anchor" href="#js-的垃圾回收" aria-hidden="true">#</a> <strong>JS 的垃圾回收</strong></h3><p>因为<strong>内存的大小是有限</strong>的，所以当<strong>内存不再需要的时候</strong>，我们需要<strong>对其进行释放</strong>，以便腾出<strong>更多的内存空间</strong>。</p><p>在<strong>手动管理内存的语言</strong>中，我们需要通过<strong>一些方式自己来释放不再需要的内存，比如 free 函数</strong>： 但是这种管理的方式其实非常的低效，影响我们编写逻辑的代码的效率； 并且这种方式对开发者的要求也很高，并且一不小心就会产生内存泄露； 所以大部分<strong>现代的编程语言都是有自己的垃圾回收机制</strong>：</p><p>垃圾回收的英文是 Garbage Collection，简称 GC；</p><p>对于那些不再使用的对象，我们都称之为是垃圾，它需要被回收，以释放更多的内存空间；而我们的语言运行环境，比如 Java 的运行环境 JVM，JavaScript 的运行环境 js 引擎都会内存 <strong>垃圾回收器</strong>； 垃圾回收器我们也会简称为 GC，所以在很多地方你看到 GC 其实指的是垃圾回收器；但是这里又出现了另外一个很关键的问题：<strong>GC 怎么知道哪些对象是不再使用的呢？</strong></p><h3 id="常见的-gc-的算法"><a class="header-anchor" href="#常见的-gc-的算法" aria-hidden="true">#</a> 常见的 GC 的算法</h3><p><strong>引用计数</strong></p><ul><li>当一个对象有一个引用指向它时，那么这个对象的引用就+1，当一个对象的引用为 0 时，这个对象就可以被销毁掉；</li><li>这个算法有一个很大的弊端就是会产生循环引用</li></ul><img src="/interview/assets/引用计数.cc7d78e4.png" alt="引用计数" style="zoom:50%;"><p><strong>标记清除：</strong></p><ul><li>这个算法是设置一个根对象（root object），垃圾回收器会定期从这个根开始，找所有从根开始有引用到的对象，对于哪些没有引用到的对象，就认为是不可用的对象；</li><li>这个算法可以很好的解决循环引用的问题； <img src="/interview/assets/标记清除.d9d12697.png" alt="引用计数" style="zoom:50%;"></li></ul><p>JS 引擎比较广泛的采用的就是标记清除算法，当然类似于 V8 引擎为了进行更好的优化，它在算法的实现细节上也会结合</p><p>一些其他的算法。</p><h2 id="this-指向"><a class="header-anchor" href="#this-指向" aria-hidden="true">#</a> This 指向</h2><p>This 的 四个基本绑定规则</p><ul><li>绑定一：默认绑定；</li><li>绑定二：隐式绑定；</li><li>绑定三：显示绑定；</li><li>绑定四：new 绑定；</li></ul><p><strong>默认绑定</strong></p><p>独立的函数调用我们可以理解成函数没有被绑定到某个对象上进行调用</p><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">fun1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">fun1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">&quot;why&quot;</span><span class="token punctuation">,</span>
  <span class="token function-variable function">bar</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token function">foo</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>bar<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//  这里就是默认绑定到了 window</span>
</code></pre></div><p><strong>隐式绑定</strong></p><p>也就是它的调用位置中，是通过某个对象发起的函数调用</p><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">var</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">&quot;obj1&quot;</span><span class="token punctuation">,</span>
  foo<span class="token operator">:</span> foo<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">var</span> obj2 <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">&quot;obj2&quot;</span><span class="token punctuation">,</span>
  obj1<span class="token operator">:</span> obj1<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

obj2<span class="token punctuation">.</span>obj1<span class="token punctuation">.</span><span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>显示绑定</strong></p><p>隐式绑定有一个前提条件：</p><ul><li>必须在调用的对象内部有一个对函数的引用（比如一个属性）；</li><li>如果没有这样的引用，在进行调用时，会报找不到该函数的错误；</li><li>正是通过这个引用，间接的将 this 绑定到了这个对象上；</li></ul><p>如果我们不希望在 <strong>对象内部</strong> 包含这个函数的引用，同时又希望在这个对象上进行强制调用</p><p>JavaScript 所有的函数都可以使用 call 和 apply 方法（这个和 Prototype 有关）。</p><p>其实非常简单，第一个参数是相同的，后面的参数，apply 为数组，call 为参数列表；</p><p>在调用这个函数时，会将 this 绑定到这个传入的第一个对象中</p><p><strong>call、apply、bind</strong></p><div class="language-"><pre><code>function foo(){
  console.log(this);
}

foo.call(window) // window
foo.call({name: &#39;tzw&#39;}) //  {name: &#39;tzw&#39;}
foo.apply(123)  //  Number 对象 临时存放123   Number(123)
</code></pre></div><p><strong>如果我们希望一个函数总是显示的绑定到一个对象上</strong></p><p><strong>bind</strong></p><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">&quot;tzw&quot;</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> bar <span class="token operator">=</span> <span class="token function">foo</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//  { name : &#39;tzw&#39;}</span>
</code></pre></div><p>*new 绑定**</p><ol><li><p>创建一个全新的对象；</p></li><li><p>这个新对象会被执行 prototype 连接；</p></li><li><p>这个新对象会绑定到函数调用的 this 上（this 的绑定在这个步骤完成）；</p></li><li><p>如果函数没有返回其他对象，表达式会返回这个新对象；</p><p><strong>JavaScript 的内置函数，或者一些第三方库中的内置函数中的 this 绑定</strong><img src="/interview/assets/内置函数的this绑定.703f83e2.png" alt="引用计数" style="zoom:100%;"></p></li></ol><p><strong>规则优先级</strong></p><p><strong>1.默认规则的优先级最低</strong></p><p>毫无疑问，默认规则的优先级是最低的，因为存在其他规则时，就会通过其他规则的方式来绑定 this</p><p><strong>2.显示绑定优先级高于隐式绑定</strong></p><p>代码测试</p><p><strong>3.new 绑定优先级高于隐式绑定</strong></p><p>代码测试</p><p><strong>4.new 绑定优先级高于 bind</strong></p><p>new 绑定和 call、apply 是不允许同时使用的，所以不存在谁的优先级更高</p><p>new 绑定可以和 bind 一起使用，new 绑定优先级更高</p><p>代码测试</p><p><strong>如果在显示绑定中，我们传入一个 null 或者 undefined，那么这个显示绑定会被忽略，使用默认规则</strong><img src="/interview/assets/忽略显示绑定的情况.beaeeacd.png" alt="忽略显示绑定的情况" style="zoom:100%;"></p><p><strong>ES6 箭头函数</strong></p><p>在 ES6 中新增一个非常好用的函数类型：箭头函数</p><p>箭头函数不使用 this 的四种标准规则（也就是不绑定 this），而是根据外层作用域来决定 this。</p><p>我们来看一个模拟网络请求的案例：</p><p>这里我使用 setTimeout 来模拟网络请求，请求到数据后如何可以存放到 data 中呢？</p><p>我们需要拿到 obj 对象，设置 data；</p><p>但是直接拿到的 this 是 window，我们需要在外层定义：</p><p>var _this = this</p><p>在 setTimeout 的回调函数中使用_this 就代表了 obj 对象</p><p>之前的代码在 ES6 之前是我们最常用的方式，从 ES6 开始，我们会使用箭头函数：</p><p>为什么在 setTimeout 的回调函数中可以直接使用 this 呢？</p><p>因为箭头函数并不绑定 this 对象，那么 this 引用就会从上层作用于中找到对应的 this <img src="/interview/assets/箭头函数的this.20ca1a4f.png" alt="箭头函数的this" style="zoom:100%;"></p><h3 id="this-面试题"><a class="header-anchor" href="#this-面试题" aria-hidden="true">#</a> this 面试题</h3><img src="/interview/assets/this面试题一.32b0dcdf.png" alt="this面试题一" style="zoom:100%;"><h2 id="实现-call-apply-bind-方法"><a class="header-anchor" href="#实现-call-apply-bind-方法" aria-hidden="true">#</a> 实现 call .apply, bind 方法</h2><p><strong>arguments</strong></p><p>array-like 意味着它不是一个数组类型，而是一个对象类型：</p><ul><li>有数组的一些特性，比如说 length，比如可以通过 index 索引来访问；</li><li>没有数组的一些方法，比如 forEach、map 等；</li></ul><p><strong>三种将类数组对象转化为数组</strong></p><div class="language-javascript"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  arr<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>arguments<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">let</span> arr1 <span class="token operator">=</span> <span class="token class-name">Array</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> arr2 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// ES6</span>
<span class="token keyword">const</span> arr3 <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>arguments<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> arr4 <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token operator">...</span>arguments<span class="token punctuation">]</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>实现 apply/call</strong></p><div class="language-javascript"><pre><code><span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">tapply</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">thisBind<span class="token punctuation">,</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  thisBind <span class="token operator">=</span> thisBind <span class="token operator">?</span> <span class="token function">Object</span><span class="token punctuation">(</span>thisBind<span class="token punctuation">)</span><span class="token operator">:</span> window     <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">这是处理 null undefined 会绑定至全局对象这里是浏览器环境 所以就是 window </span><span class="token template-punctuation string">`</span></span>
  thisBind<span class="token punctuation">.</span>fn <span class="token operator">=</span> <span class="token keyword">this</span>                                 <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Object 会处理 数字 字符串  布尔类型等 转为为对象形式</span><span class="token template-punctuation string">`</span></span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    thisBind<span class="token punctuation">.</span><span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span>                                    <span class="token comment">// 因为 apply 等方法是c++ 实现的 这里 JS 往函数的原型上添加方法</span>
  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> result <span class="token operator">=</span> thisBind<span class="token punctuation">.</span><span class="token function">fn</span><span class="token punctuation">(</span><span class="token operator">...</span>args<span class="token punctuation">)</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">delete</span> thisBind<span class="token punctuation">.</span>fn                             <span class="token comment">// 手动删除方法</span>
  <span class="token keyword">return</span> result
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">foo</span> <span class="token punctuation">(</span><span class="token parameter">num1<span class="token punctuation">,</span> num2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token string">&#39;this指向什么&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> num1<span class="token operator">+</span>num2
<span class="token punctuation">}</span>

foo<span class="token punctuation">.</span><span class="token function">tapply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span>                    <span class="token comment">//     指向的window</span>

<span class="token keyword">var</span> test <span class="token operator">=</span>  foo<span class="token punctuation">.</span><span class="token function">tapply</span><span class="token punctuation">(</span><span class="token punctuation">{</span>name<span class="token operator">:</span> <span class="token string">&#39;tzw&#39;</span><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span>        <span class="token comment">// 指向的是 {name: &#39;tzw&#39;} 对象</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>test<span class="token punctuation">,</span> <span class="token string">&#39;返回的结果&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token number">3</span>
</code></pre></div><p>因为 call 跟 apply 只是 第二个传参不同,</p><div class="language-apl"><pre><code>call<span class="token punctuation">(</span>xxx<span class="token function">,</span> arg1<span class="token function">,</span> arg2<span class="token punctuation">)</span>
apply<span class="token punctuation">(</span>xxx<span class="token function">,</span> <span class="token punctuation">[</span>arg1<span class="token function">,</span> arg2<span class="token punctuation">]</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>实现 bind</strong></p><div class="language-javascript"><pre><code><span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">tbind</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">thisbind<span class="token punctuation">,</span> args1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  thisbind <span class="token operator">=</span> thisbind <span class="token operator">?</span> <span class="token function">Object</span><span class="token punctuation">(</span>thisbind<span class="token punctuation">)</span> <span class="token operator">:</span> window<span class="token punctuation">;</span>
  thisbind<span class="token punctuation">.</span>fn <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> thisbind<span class="token punctuation">.</span><span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">...</span>args1<span class="token punctuation">,</span> <span class="token operator">...</span>args2<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter"><span class="token operator">...</span>args</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> <span class="token string">&quot;this指向&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token punctuation">[</span><span class="token operator">...</span>args<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">pre<span class="token punctuation">,</span> cur</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> pre <span class="token operator">+</span> cur<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> test <span class="token operator">=</span> <span class="token function">foo</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">&quot;eason&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="原型以及原型链"><a class="header-anchor" href="#原型以及原型链" aria-hidden="true">#</a> 原型以及原型链</h2><p>JS 中每个对象都有 一个特殊的内置属性 , [prototype] , 这个特殊的属性可以指向另外一个对象</p><p>早期的 ECMA 是没有规范 如何去查看 [prototype] 这个属性</p><p>浏览器提供了一个 属性 可以让我们查看这个原型对象</p><p><strong>--proto--</strong></p><div class="language-javascript"><pre><code><span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">.</span>__proto__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 浏览器提供的   {}</span>
<span class="token comment">//  es5 之后提供的</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">getPrototypeOf</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// {}</span>
</code></pre></div><p>这个 <strong>--proto--</strong> 也被成为 隐式原型 不会直接用这个属性</p><h3 id="隐式原型属性的作用"><a class="header-anchor" href="#隐式原型属性的作用" aria-hidden="true">#</a> 隐式原型属性的作用</h3><ol><li><p>当我们从对象中获取一个属性时, 会触发 get 操作</p></li><li><p>在当前对象中去查找对应的属性 找到就直接用</p></li><li><p>没有找到 会沿着原型链 去查找 去 prototype 中查找</p></li></ol><h3 id="函数也是一个对象-也是一个函数"><a class="header-anchor" href="#函数也是一个对象-也是一个函数" aria-hidden="true">#</a> <strong>函数也是一个对象</strong>, 也是一个函数</h3><p>函数作为对象来说也有一个 --proto-- 隐式原型, 作为函数来说 会多出一个 显示原型 [ prototype]</p><p>当通过 new 构造函数的时候 会将 创建的对象的的--prorto-- 属性 赋值给 foo.prototype</p><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

<span class="token keyword">let</span> t1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> t2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>t1<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> foo<span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>t2<span class="token punctuation">.</span>__proto__ <span class="token operator">===</span> foo<span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// true</span>
</code></pre></div><img src="/interview/assets/原型链.0e7368bc.png" style="zoom:100%;"><p><strong>修改函数的 原型对象</strong></p><p>通过 Object.defineProperty 添加 construct</p><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>foo<span class="token punctuation">,</span> <span class="token string">&quot;constructor&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  enumerable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token comment">// 可枚举</span>
  writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token comment">// 可读写</span>
  value<span class="token operator">:</span> foo<span class="token punctuation">,</span>
  configurable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token comment">// 可配置</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Object 顶层原型对象</p><ul><li><p>[Object: null prototype] {} 就是最顶层的原型</p></li><li><p>从 Object 直接创建出来的对象的原型都是 [Object: null prototype] {}</p><hr><p>Object 原型的特殊性</p><ol><li>该对象的也要原型属性,但是它的原型 --proto--指向的 null, 也就是顶层原型</li><li>该对象上有很多方法和属性</li></ol></li></ul><h3 id="函数的-proto-属性"><a class="header-anchor" href="#函数的-proto-属性" aria-hidden="true">#</a> 函数的 --proto-- 属性</h3><p>函数也是有 --proto-- 属性的 <img src="/interview/assets/函数的原型对象.add0ad34.png" style="zoom:100%;"></p><p>根据图 得出 fuction 是继承于 Object 对象的</p><h3 id="判断原型的一些方法"><a class="header-anchor" href="#判断原型的一些方法" aria-hidden="true">#</a> 判断原型的一些方法</h3><p>判断某个属性是否是在当前对象上</p><p>**obj.hasOwnPrototy(&#39;某个属性&#39;) _ // 只在当前对象上_ **</p><p><strong>instanceof //</strong></p><p><strong>in 操作符</strong></p><h3 id="对象-函数-原型-的关系"><a class="header-anchor" href="#对象-函数-原型-的关系" aria-hidden="true">#</a> <strong>对象- 函数 原型 的关系</strong></h3><p>普通的字面量创建的对象例如</p><div class="language-javascript"><pre><code><span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">// 本质是由 Object（） 函数创建出来的对象</span>
  name<span class="token operator">:</span> <span class="token string">&quot;tzw&quot;</span><span class="token punctuation">,</span> <span class="token comment">//  所以  obj.__proto__ === Object.prototype</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>对象</strong>是 存在一个 隐式原型对象 --proto--</p><p><strong>函数</strong> 是函数 存在一个 显示原型对象 <strong>foo. prototype = { constructor :foo }</strong></p><p>​ 函数本身 也是一个对象 <strong>foo.--proto-- = {constructor :Function }**</strong> 因为 Function.prototype = { constructor：Function }</p><p>是由 new Function（） 构造函数创建出来的 在全局 会有 function Function（）{} 这个类</p><p>​</p><p>函数本身的 foo.prototype 跟 foo.--proto-- 是不相等的</p><p>Function 这个全局类 比较特殊 Function.prototype = Funvion.--proto-- <img src="/interview/assets/原型树图.5adbaa2c.png" style="zoom:100%;"></p><h2 id="原型继承"><a class="header-anchor" href="#原型继承" aria-hidden="true">#</a> 原型继承</h2><p>通过原型链实现的继承的弊端</p><ol><li>通过 继承得到的对象 打印不出 继承于父类的属性</li><li>子类对象之间 会相互影响 (获取 修改 引用类型的值)</li><li>无法接受参数</li></ol><p>借用 构造函数 实现继承</p><hr><h3 id="将-子类的原型指向-父类的原型"><a class="header-anchor" href="#将-子类的原型指向-父类的原型" aria-hidden="true">#</a> 将 子类的原型指向 父类的原型</h3><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token function">Student</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> song</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">Person</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">,</span> song<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">Person</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> song</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>song <span class="token operator">=</span> song<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token class-name">Person</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sing</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;DUO!--&gt;&gt; &quot;</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>song<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token class-name">Student</span><span class="token punctuation">.</span>prototype <span class="token operator">=</span> <span class="token class-name">Person</span><span class="token punctuation">.</span>prototype<span class="token punctuation">;</span>

<span class="token keyword">const</span> t <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Student</span><span class="token punctuation">(</span><span class="token string">&quot;tzw&quot;</span><span class="token punctuation">,</span> <span class="token number">1874</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
t<span class="token punctuation">.</span><span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// duo  --&gt;&gt; 1874</span>
</code></pre></div><p>弊端</p><ol><li>会影响 父类的原型, 会把父类原型 添加很多不必要的属性</li><li>也会影响 继承这个父类的 其他对象</li></ol><hr><h3 id="原型式-继承"><a class="header-anchor" href="#原型式-继承" aria-hidden="true">#</a> 原型式 -- 继承</h3><p>通过创建一个 对象, 使这个对象的原型对象 指向 父类对象</p><div class="language-javascript"><pre><code><span class="token keyword">const</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">&quot;tzw&quot;</span><span class="token punctuation">,</span>
  age<span class="token operator">:</span> <span class="token number">23</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">createObjProto1</span><span class="token punctuation">(</span><span class="token parameter">o</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">//  第一种</span>
  <span class="token keyword">var</span> newobj <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
  Objcet<span class="token punctuation">.</span><span class="token function">setPrototypeOf</span><span class="token punctuation">(</span>newobj<span class="token punctuation">,</span> o<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> newobj<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">createObjProto</span><span class="token punctuation">(</span><span class="token parameter">o</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// 第二种</span>
  <span class="token keyword">function</span> <span class="token function">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
  fn<span class="token punctuation">.</span>prototype <span class="token operator">=</span> o<span class="token punctuation">;</span>
  <span class="token keyword">var</span> newObjProto <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">fn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> newObjProto<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token number">11111111111111111111111111111111111111111111111111111111</span><span class="token punctuation">;</span>

<span class="token keyword">var</span> info <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>Obj<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 第三种</span>

<span class="token keyword">var</span> info <span class="token operator">=</span> <span class="token function">createObjProto</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>info<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//  {}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>info<span class="token punctuation">.</span>__proto__<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { name: &#39;tzw&#39;, age: 23}</span>
</code></pre></div><h3 id="寄生组合式继承"><a class="header-anchor" href="#寄生组合式继承" aria-hidden="true">#</a> 寄生组合式继承</h3><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token function">Person</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token class-name">Person</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sing</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;Eason&quot;</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">singer</span><span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age<span class="token punctuation">,</span> title<span class="token punctuation">,</span> context</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">Person</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">,</span> name<span class="token punctuation">,</span> age<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>context <span class="token operator">=</span> context<span class="token punctuation">;</span>
  <span class="token keyword">this</span><span class="token punctuation">.</span>title <span class="token operator">=</span> title<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
singer<span class="token punctuation">.</span>prototype <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token class-name">Person</span><span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 通过 将新对象 指向父类原型对象</span>
Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>singer<span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> <span class="token string">&quot;constructor&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  <span class="token comment">///  因为创建出来用于继承的对象 没有 constructor 所有会往原型链上找 这里手动设置</span>
  enumerable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
  writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  configurable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  value<span class="token operator">:</span> singer<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
singer<span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">sing1</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>title <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>context<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> eason <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">singer</span><span class="token punctuation">(</span><span class="token string">&quot;Eason&quot;</span><span class="token punctuation">,</span> <span class="token number">45</span><span class="token punctuation">,</span> <span class="token string">&quot;葡萄成熟时&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;差不多冬至&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>eason<span class="token punctuation">)</span><span class="token punctuation">;</span>
eason<span class="token punctuation">.</span><span class="token function">sing1</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
eason<span class="token punctuation">.</span><span class="token function">sing</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>弊端</p><ol><li>如果创建 多个子类型的对象 ,需要重写 继承的重要代码</li></ol><p>解决 : 封装一个工具函数</p><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token function">setProto</span><span class="token punctuation">(</span><span class="token parameter">sonType<span class="token punctuation">,</span> superType</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  sonType<span class="token punctuation">.</span>prototype <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>superType<span class="token punctuation">.</span>prototype<span class="token punctuation">)</span><span class="token punctuation">;</span>
  Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>sonType<span class="token punctuation">.</span>prototype<span class="token punctuation">,</span> <span class="token string">&quot;constructor&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
    enumerable<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
    writable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    configurable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
    value<span class="token operator">:</span> sonType<span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="闭包"><a class="header-anchor" href="#闭包" aria-hidden="true">#</a> 闭包</h2><p>函数: 独立的 function, 就是称之为一个函数</p><p>方法: 当我们的函数是属于某一个对象的时候, 就是称这个函数为这个对象的方法</p><h3 id="闭包的定义"><a class="header-anchor" href="#闭包的定义" aria-hidden="true">#</a> 闭包的定义</h3><p>这里先来看一下闭包的定义，分成两个：在计算机科学中和在 JavaScript 中。</p><p>在计算机科学中对闭包的定义（维基百科）：</p><ul><li>闭包（英语：Closure），又称<strong>词法闭包</strong>（Lexical Closure）或<strong>函数闭包</strong>（function closures）；</li><li>是在支持 <strong>头等函数</strong> 的编程语言中，实现词法绑定的一种技术；</li><li>闭包在实现上是一个结构体，它存储了一个函数和一个关联的环境（相当于一个符号查找表）；</li><li>闭包跟函数最大的区别在于，当捕捉闭包的时候，它的 <strong>自由变量</strong> 会在捕捉时被确定，这样即使脱离了捕捉时的上下文，它也能照常运行；</li></ul><p>MDN 对 JavaScript 闭包的解释：</p><p>一个函数和对其周围状态（<strong>lexical environment，词法环境</strong>）的引用捆绑在一起（或者说函数被引用包围），这样的组合就是<strong>闭包</strong>（<strong>closure</strong>）；</p><p>也就是说，闭包让你可以在一个内层函数中访问到其外层函数的作用域；</p><p>在 JavaScript 中，每当创建一个函数，闭包就会在函数创建的同时被创建出来；</p><p>那么我的理解和总结：</p><ul><li><p>一个普通的函数 function，如果它可以访问外层作用于的自由变量，那么这个函数就是一个闭包；</p></li><li><p>从广义的角度来说：JavaScript 中的函数都是闭包；</p></li><li><p>从狭义的角度来说：JavaScript 中一个函数，如果访问了外层作用域的变量，那么它是一个闭包</p><h3 id="闭包的访问过程"><a class="header-anchor" href="#闭包的访问过程" aria-hidden="true">#</a> 闭包的访问过程</h3><img src="/interview/assets/闭包的访问过程.91523e50.png" alt="闭包的访问过程" style="zoom:100%;"></li></ul><p><strong>闭包的执行过程</strong></p><p>那么函数继续执行呢？</p><ul><li>这个时候 makeAdder 函数执行完毕，正常情况下我们的 AO 对象会被释放；</li><li>但是因为在 0xb00 的函数中有作用域引用指向了这个 AO 对象，所以它不会被释放掉 <img src="/interview/assets/闭包的执行过程.f1a5458c.png" alt="闭包的执行过程" style="zoom:100%;"><strong>闭包的内存泄露</strong></li></ul><p>那么我们为什么经常会说闭包是有内存泄露的呢？</p><ul><li>在上面的案例中，如果后续我们不再使用 add10 函数了，那么该函数对象应该要被销毁掉，并且其引用着的父 作用域 AO 也应该被销毁掉；</li><li>但是因为在全局作用域下 add10 变量对 0xb00 的函数对象有引用，而 0xb00 的作用域中 AO（0x200）有引用，所以最终造成这些内存都是无法被释放；</li><li>所以我们经常说的闭包会造成内存泄露，其实就是刚才的引用链中的所有对象都是无法释放的；</li></ul><p>那么，怎么解决这个问题呢？</p><ul><li>因为当将 add10 设置为 null 时，就不再对函数对象 0xb00 有引用，那么对应的 AO 对象 0x200 也就不可达了；</li><li>在 GC 的下一次检测中，它们就会被销毁掉</li></ul><p><strong>AO 不使用的属性</strong></p><ul><li>在 ECMA 规范中闭包中没有使用的自由变量是不会销毁的</li><li>但是在 JS 引擎中 会进行优化 所以在最后实际开发代码中会将闭包中未使用的属性删除</li></ul><p>闭包的使用</p><h2 id="es6-知识"><a class="header-anchor" href="#es6-知识" aria-hidden="true">#</a> ES6 知识</h2><p>解构赋值 以及字面量增强</p><h3 id="let-const-以及-作用域提升"><a class="header-anchor" href="#let-const-以及-作用域提升" aria-hidden="true">#</a> let const 以及 作用域提升</h3><p>const 声明的 变量如果是引用类型， 那么指向的是引用地址，不能改变引用类型的地址</p><p>**创建执行上下文时， 会创建词法环境 ，变量已经被创建了，但是这些变量是不能访问的，直到变量被赋值 ** ecma262 规范</p><ul><li>作用域提升： 在变量声明的作用域当中，如果这个变量可以在声明之前被访问，就是作用域提升</li><li>但是 let / const 虽然被创建出来了， 但是并不能访问，所以并不能称之为作用域提升</li></ul><p><strong>创建的变量是添加到什么地方</strong></p><p>在全局通过 var 来声明 一个变量， 会在 window 上添加一个属性 被关联到 变量环境中</p><p>通过 let/ const 被关联到 变量环境中</p><ul><li><p>ES6 之前: 每一个执行上下文会被关联到一个变量对象 VO(variable object) ,在源代码中的变量和函数会被作为属性添加到 VO 中, 对于函数来说,参数也会被添加到 VO 中</p></li><li><p>ES6 之后 每一个执行上下文会被关联到一个变量环境,(VariableEnvironment)中, 在执行代码中变量和函数的声明会作为环境记录(Environment)添加到变量环境中,对于函数来说,参数也会被作为环境记录添加到变量环境中</p></li></ul><p>早期的 浏览器 是通过 v8 引擎 window 实现 vo 变量对象的</p><p>根据不同的 js 引擎 所以 v8 实现这个 ve 规范 声明了一个 variable：VariableMap 这个对象中 hashmap 存储 了</p><h3 id="三个不同的作用域"><a class="header-anchor" href="#三个不同的作用域" aria-hidden="true">#</a> <strong>三个不同的作用域</strong></h3><p>​ 全局作用域;; 函数作用域 :function() {} 块级作用域 {}</p><ul><li>作用范围 <ul><li><code>var命令</code>在全局代码中执行</li><li><code>const命令</code>和<code>let命令</code>只能在代码块中执行</li></ul></li><li>赋值使用 <ul><li><code>const命令</code>声明常量后必须立马赋值</li><li><code>let命令</code>声明变量后可立马赋值或使用时赋值</li></ul></li></ul><blockquote><p>重点难点</p></blockquote><ul><li>不允许重复声明</li><li>未定义就使用会报错：<code>const命令</code>和<code>let命令</code>不存在变量提升</li><li>暂时性死区：在代码块内使用<code>const命令</code>和<code>let命令</code>声明变量之前，该变量都不可用</li></ul><p><strong>暂时性死区</strong> 在变量声明之前 不能访问</p><p><strong>模板字符串</strong> 模板字符串可以 调用函数 foo ··</p><p>标签模板字符串</p><div class="language-javascript"><pre><code><span class="token comment">//  ${} 会把字符串分割成一个数组，作为第一个参数  第二个参数是第一个 ￥{}的</span>
<span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token parameter">m<span class="token punctuation">,</span> n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>m<span class="token punctuation">,</span> n<span class="token punctuation">,</span> <span class="token string">&quot;=-========---&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> name <span class="token operator">=</span> <span class="token string">&quot;why&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> age <span class="token operator">=</span> <span class="token number">12</span><span class="token punctuation">;</span>

foo<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">he</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token number">11</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> tzw</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token number">22</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">eason</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>
</code></pre></div><h3 id="symbol"><a class="header-anchor" href="#symbol" aria-hidden="true">#</a> symbol</h3><p>在给对象添加一个值 可能会覆盖原来对象的属性</p><p>为了声明 独一无二的值 是一个函数 生成一个 symboy 值</p><p>Symbol 作为 key 的几种写法</p><div class="language-javascript"><pre><code><span class="token keyword">const</span> s1 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">&#39;aaa&#39;</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> s2 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">&#39;bbb&#39;</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> s3 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">&#39;ccc&#39;</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> s4 <span class="token operator">=</span> <span class="token function">Symbol</span><span class="token punctuation">(</span><span class="token string">&#39;ddd&#39;</span><span class="token punctuation">)</span>

<span class="token keyword">const</span> obj <span class="token operator">=</span><span class="token punctuation">{</span>
  <span class="token punctuation">[</span>s1<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">&#39;tzw&#39;</span><span class="token punctuation">,</span>
  <span class="token punctuation">[</span>s1<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token string">&#39;eason&#39;</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> obj1<span class="token punctuation">[</span>s3<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">&#39;ooo&#39;</span>

Object<span class="token punctuation">.</span><span class="token function">defineProperty</span><span class="token punctuation">(</span>obj<span class="token punctuation">,</span>s4<span class="token punctuation">,</span><span class="token punctuation">{</span>
  value<span class="token operator">:</span><span class="token string">&#39;qqq&#39;</span><span class="token punctuation">,</span>
  writable<span class="token operator">:</span><span class="token boolean">true</span><span class="token punctuation">,</span>
  enumerable<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
  configurable<span class="token operator">:</span> <span class="token boolean">true</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>获取 symbol 属性 通过 【】 不能通过 。 也不能遍历 这些 symbol Object.keys() 获取不到</p><div class="language-javascript"><pre><code><span class="token comment">// 遍历对象中的所有SYmbol属性</span>
<span class="token keyword">const</span> keys <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">getOwnPropertySymbols</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> i <span class="token keyword">of</span> keys<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h3 id="set-weakmap-与-map"><a class="header-anchor" href="#set-weakmap-与-map" aria-hidden="true">#</a> Set / WeakMap 与 Map</h3><h5 id="set"><a class="header-anchor" href="#set" aria-hidden="true">#</a> Set</h5><ul><li>定义：类似于数组的数据结构，成员值都是唯一且没有重复的值</li><li>声明：<code>const set = new Set(arr)</code></li><li>入参：具有<code>Iterator接口</code>的数据结构</li><li>属性 <ul><li><strong>constructor</strong>：构造函数，返回 Set</li><li><strong>size</strong>：返回实例成员总数</li></ul></li><li>方法 <ul><li><strong>add()</strong>：添加值，返回实例</li><li><strong>delete()</strong>：删除值，返回布尔</li><li><strong>has()</strong>：检查值，返回布尔</li><li><strong>clear()</strong>：清除所有成员</li><li><strong>keys()</strong>：返回以属性值为遍历器的对象</li><li><strong>values()</strong>：返回以属性值为遍历器的对象</li><li><strong>entries()</strong>：返回以属性值和属性值为遍历器的对象</li><li><strong>forEach()</strong>：使用回调函数遍历每个成员</li></ul></li></ul><blockquote><p>应用场景</p></blockquote><ul><li>去重字符串：<code>[...new Set(str)].join(&quot;&quot;)</code></li><li>去重数组：<code>[...new Set(arr)]</code>或<code>Array.from(new Set(arr))</code></li><li>集合数组 <ul><li>声明：<code>const a = new Set(arr1)</code>、<code>const b = new Set(arr2)</code></li><li>并集：<code>new Set([...a, ...b])</code></li><li>交集：<code>new Set([...a].filter(v =&gt; b.has(v)))</code></li><li>差集：<code>new Set([...a].filter(v =&gt; !b.has(v)))</code></li></ul></li><li>映射集合 <ul><li>声明：<code>let set = new Set(arr)</code></li><li>映射：<code>set = new Set([...set].map(v =&gt; v * 2))</code>或<code>set = new Set(Array.from(set, v =&gt; v * 2))</code></li></ul></li></ul><blockquote><p>重点难点</p></blockquote><ul><li>遍历顺序：插入顺序</li><li>没有键只有值，可认为键和值两值相等</li><li>添加多个<code>NaN</code>时，只会存在一个<code>NaN</code></li><li>添加相同的对象时，会认为是不同的对象</li><li>添加值时不会发生类型转换(<code>5 !== &quot;5&quot;</code>)</li><li><code>keys()</code>和<code>values()</code>的行为完全一致，<code>entries()</code>返回的遍历器同时包括键和值且两值相等</li></ul><h5 id="weakset"><a class="header-anchor" href="#weakset" aria-hidden="true">#</a> WeakSet</h5><ul><li>定义：和 Set 结构类似，成员值只能是对象</li><li>声明：<code>const set = new WeakSet(arr)</code></li><li>入参：具有<code>Iterator接口</code>的数据结构</li><li>属性 <ul><li><strong>constructor</strong>：构造函数，返回 WeakSet</li></ul></li><li>方法 <ul><li><strong>add()</strong>：添加值，返回实例</li><li><strong>delete()</strong>：删除值，返回布尔</li><li><strong>has()</strong>：检查值，返回布尔</li></ul></li></ul><blockquote><p>应用场景</p></blockquote><ul><li>储存 DOM 节点：DOM 节点被移除时自动释放此成员，不用担心这些节点从文档移除时会引发内存泄漏</li><li>临时存放一组对象或存放跟对象绑定的信息：只要这些对象在外部消失，它在<code>WeakSet结构</code>中的引用就会自动消</li></ul><blockquote><p>重点难点</p></blockquote><ul><li>成员都是<code>弱引用</code>，垃圾回收机制不考虑<code>WeakSet结构</code>对此成员的引用</li><li>成员不适合引用，它会随时消失，因此 ES6 规定<code>WeakSet结构不可遍历</code></li><li>其他对象不再引用成员时，垃圾回收机制会自动回收此成员所占用的内存，不考虑此成员是否还存在于<code>WeakSet结构</code>中</li></ul><h3 id="map"><a class="header-anchor" href="#map" aria-hidden="true">#</a> Map</h3><h5 id="map-1"><a class="header-anchor" href="#map-1" aria-hidden="true">#</a> Map</h5><ul><li>定义：类似于对象的数据结构，成员键是任何类型的值</li><li>声明：<code>const set = new Map(arr)</code></li><li>入参：具有<code>Iterator接口</code>且每个成员都是一个双元素数组的数据结构</li><li>属性 <ul><li><strong>constructor</strong>：构造函数，返回 Map</li><li><strong>size</strong>：返回实例成员总数</li></ul></li><li>方法 <ul><li><strong>get()</strong>：返回键值对</li><li><strong>set()</strong>：添加键值对，返回实例</li><li><strong>delete()</strong>：删除键值对，返回布尔</li><li><strong>has()</strong>：检查键值对，返回布尔</li><li><strong>clear()</strong>：清除所有成员</li><li><strong>keys()</strong>：返回以键为遍历器的对象</li><li><strong>values()</strong>：返回以值为遍历器的对象</li><li><strong>entries()</strong>：返回以键和值为遍历器的对象</li><li><strong>forEach()</strong>：使用回调函数遍历每个成员</li></ul></li></ul><blockquote><p>重点难点</p></blockquote><ul><li>遍历顺序：插入顺序</li><li>对同一个键多次赋值，后面的值将覆盖前面的值</li><li>对同一个对象的引用，被视为一个键</li><li>对同样值的两个实例，被视为两个键</li><li>键跟内存地址绑定，只要内存地址不一样就视为两个键</li><li>添加多个以<code>NaN</code>作为键时，只会存在一个以<code>NaN</code>作为键的值</li><li><code>Object结构</code>提供<code>字符串—值</code>的对应，<code>Map结构</code>提供<code>值—值</code>的对应</li></ul><h5 id="weakmap"><a class="header-anchor" href="#weakmap" aria-hidden="true">#</a> WeakMap</h5><ul><li>定义：和 Map 结构类似，成员键只能是对象</li><li>声明：<code>const set = new WeakMap(arr)</code></li><li>入参：具有<code>Iterator接口</code>且每个成员都是一个双元素数组的数据结构</li><li>属性 <ul><li><strong>constructor</strong>：构造函数，返回 WeakMap</li></ul></li><li>方法 <ul><li><strong>get()</strong>：返回键值对</li><li><strong>set()</strong>：添加键值对，返回实例</li><li><strong>delete()</strong>：删除键值对，返回布尔</li><li><strong>has()</strong>：检查键值对，返回布尔</li></ul></li></ul><blockquote><p>应用场景</p></blockquote><ul><li>储存 DOM 节点：DOM 节点被移除时自动释放此成员键，不用担心这些节点从文档移除时会引发内存泄漏</li><li>部署私有属性：内部属性是实例的弱引用，删除实例时它们也随之消失，不会造成内存泄漏</li></ul><blockquote><p>重点难点</p></blockquote><ul><li>成员键都是<code>弱引用</code>，垃圾回收机制不考虑<code>WeakMap结构</code>对此成员键的引用</li><li>成员键不适合引用，它会随时消失，因此 ES6 规定<code>WeakMap结构不可遍历</code></li><li>其他对象不再引用成员键时，垃圾回收机制会自动回收此成员所占用的内存，不考虑此成员是否还存在于<code>WeakMap结构</code>中</li><li>一旦不再需要，成员会自动消失，不用手动删除引用</li><li>弱引用的<code>只是键而不是值</code>，值依然是正常引用</li><li>即使在外部消除了成员键的引用，内部的成员值依然存在</li></ul><p>ES7 》》》ES12 系列</p><h3 id="es7"><a class="header-anchor" href="#es7" aria-hidden="true">#</a> ES7</h3><p>Array Include 判断数组中是否包含某个元素 包含的话 返回 true</p><p>乘方运算符 3 **3 Math.pow(3,3)</p><h3 id="es8"><a class="header-anchor" href="#es8" aria-hidden="true">#</a> ES8</h3><p><strong>Object.values</strong> 获取到所有的 values 返回一个数组 如果传入一个数组返回数组本身，传入一个字符串，会返回字符串数组</p><p><strong>Object.keys</strong> （es5 之前就有）</p><p><strong>Object.entries</strong> 可以获取到一个数组 包括 key，value 【【key：valye】】</p><p>用法： 例如将对象转换成 数组然后进行 一些数组的遍历操作</p><hr><p><strong>String Padding</strong> 字符串填充</p><p><strong>padStart()</strong> 往字符串前面填充 第一个参数为填充后的位数，第二个参数为填充的内容 string.padStart(15, &#39;****&#39;)</p><p><strong>padEnd()</strong> 往字符串后面填充 同上</p><p>用法 隐藏身份证号 或者手机号一些位数</p><hr><h3 id="es10"><a class="header-anchor" href="#es10" aria-hidden="true">#</a> ES10</h3><p><strong>flat</strong> / <strong>flat-map</strong></p><p>数组扁平化 arr .flat() 第一个参数 接受一个 降维 的维度 按照一个可指定的深度递归遍历数组，并将所有元素与遍历的子数组的元素合并到一个新数组返回</p><p>flatmap 首先使用映射函数映射每个元素，然后将结果压缩成一个新数组</p><ol><li>flatMap 是先进行 map 操作，然后在做 flat 操作</li><li>默认 flat 的维度为 1</li></ol><hr><p><strong>Object.fromEntries</strong></p><p>将 <strong>Object.entries</strong> 可以获取到一个数组 包括 key，value 【【key：valye】】 的格式 转化成原来的对象 {key：value }</p><p>引用场景 对于 url http：// www。xxx。com ？name=key&amp;age=18&amp;sad=555</p><hr><p>trimStart(): 去除头部的空格</p><p>trimEnd(): 去除尾部的空给</p><hr><h3 id="es-11"><a class="header-anchor" href="#es-11" aria-hidden="true">#</a> ES 11</h3><p><strong>Bigint</strong> 为了表示过大的数字 int 类型之前最大 MAX_SAFE_INTEGER</p><p>10n 转成大数字类型 BigInt（xxx）</p><hr><p>空值合并操作运算符 零 跟空字符串 会被判断成 false 为了使用 零 跟空字符串</p><p><strong>？？</strong> const bar = bar： ’defaualt value‘</p><p>?. 可选链 xxxx？. xxx 为了代码更加简洁 跟安全</p><hr><p><strong>globalThis</strong> 获取某个环境的全局对象</p><p>在浏览器环境下 window 全局对象 this 是 window</p><p>在 node 环境下 global 全局对象 this 是{}</p><hr><p>for 。。。 in 标准化</p><p>for in 遍历的 item 是 key</p><hr><p>Dynamic Import 动态导入</p><p>Promise。allsettled</p><p>imort meta</p><hr><h3 id="es12"><a class="header-anchor" href="#es12" aria-hidden="true">#</a> ES12</h3><p>垃圾回收机制 监听 数据被销毁 时的监听 新增了一个类 FinalizationRegistry 类</p><div class="language-javascript"><pre><code><span class="token keyword">const</span> finalRegistry <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FinalizationRegistry</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;注册过的对象被销毁了&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> obj <span class="token operator">=</span> <span class="token punctuation">{</span> name<span class="token operator">:</span> <span class="token string">&quot;why&quot;</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>

finalRegistry<span class="token punctuation">.</span><span class="token function">register</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>

obj <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
</code></pre></div><p>通过 weakRef 类 创建一个弱引用 对象</p><div class="language-javascript"><pre><code><span class="token comment">//let info  = new weakRef(xx)</span>
<span class="token comment">//info.deref().name)</span>
</code></pre></div><p>通过 .deref().xxx 获取属性</p><hr><p>逻辑赋值运算符</p><p>| | = &amp; &amp; = ？？=</p><div class="language-javascript"><pre><code><span class="token keyword">let</span> info <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span>
info <span class="token operator">=</span> info <span class="token operator">||</span> <span class="token string">&quot;default value&quot;</span><span class="token punctuation">;</span>
<span class="token comment">//  &gt;&gt; info || = &#39;default value&#39;</span>
</code></pre></div><hr><p>数字分隔符 215--415--4546-326--564</p><p>replaceAll 字符串替换</p><h2 id="promise"><a class="header-anchor" href="#promise" aria-hidden="true">#</a> Promise</h2><h3 id="promise-的基本使用-：是一个类-是一种规范机制-来保证设计异步"><a class="header-anchor" href="#promise-的基本使用-：是一个类-是一种规范机制-来保证设计异步" aria-hidden="true">#</a> promise 的基本使用 ：是一个类 是一种规范机制 来保证设计异步</h3><div class="language-java"><pre><code><span class="token comment">//   promise 传入一个立即执行函数 executor</span>
<span class="token comment">//  这个函数 会被立即执行 并且传入两个参数  resolve, reject</span>
<span class="token comment">//  resolve: 成功的回调函数</span>
<span class="token comment">//  reject: 失败的回调函数</span>
<span class="token keyword">const</span> p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span>reject<span class="token punctuation">)</span><span class="token operator">=</span><span class="token operator">&gt;</span><span class="token punctuation">{</span>
  <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;executor 函数会被立即执行&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>

 <span class="token comment">// then 方法传入的回调函数 ,会在Promise 执行 resolve函数时 被回调  并传入成功信息</span>
 <span class="token comment">//  失败执行第二个函数   并且传入失败信息</span>
p<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token operator">=</span><span class="token operator">&gt;</span><span class="token punctuation">{</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">(</span>err
  <span class="token punctuation">)</span><span class="token operator">=</span><span class="token operator">&gt;</span><span class="token punctuation">{</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><h3 id="promise-状态"><a class="header-anchor" href="#promise-状态" aria-hidden="true">#</a> promise 状态</h3><div class="language-javascript"><pre><code><span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span>reject</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;-------&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token comment">//     这个函数一定会执行 exectuor  处于 pendding 状态  悬而未决状态</span>
  <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token punctuation">)</span>                      <span class="token comment">//     状态变成 resoved 状态  敲代</span>
                                <span class="token comment">//      reject（）   状态变成 rejected 状态  失败</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>res<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token parameter">err</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">,</span><span class="token string">&#39;err&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>状态一旦 确定下来 那么状态就被锁定 不可更改</p><h3 id="resolve-（参数）"><a class="header-anchor" href="#resolve-（参数）" aria-hidden="true">#</a> resolve （参数）</h3><ol><li><p>普通的值或者对象</p></li><li><p>传入一个 promise</p><ul><li>那么当前的状态会由传入的 promise 来决定</li><li>相当于状态移交</li></ul></li><li><p>如果传入 的是一个 带有 thanable 对象</p><ul><li>then 方法会自动执行</li><li>then 方法会接收 resolve， rejcet</li><li>由这个 then 方法 决定后续状态</li></ul></li></ol><h3 id="then-方法-对象的方法，需要创建-promise-实例-放在-promise-的原型上的，-promise-ptototype-then-上"><a class="header-anchor" href="#then-方法-对象的方法，需要创建-promise-实例-放在-promise-的原型上的，-promise-ptototype-then-上" aria-hidden="true">#</a> then 方法 对象的方法，需要创建 promise 实例 放在 Promise 的原型上的， Promise. ptototype.then 上</h3><p>p.then(&#39;calback&#39;) 当 p 执行了 resolve （） ,这个 promise 的所有 then 里面的回调函数就会被立即执行</p><p>同一个 Primise 可以被多次调用 then 方法</p><p>p.then(res2=&gt;{ })</p><p>then 方法传入的回调函数 也可以有返回值 也是 promise 对象</p><ul><li>如果是返回一个普通的<strong>数字/对象/字符串/undefined</strong>，new promise（res=》{ resolve（resolve） }）</li><li>链式调用 then 的话 是上一个返回的 promise 的值</li><li>如果返回的是一个 promise 会把这个 promise 作为当前的 promise 状态也由返回的 promise 状态决定下一次 then</li><li>如果返回 的是一个 then able 也是返回一个新 promise</li></ul><h3 id="catch（）错误异常-拒绝捕获"><a class="header-anchor" href="#catch（）错误异常-拒绝捕获" aria-hidden="true">#</a> Catch（）错误异常/拒绝捕获</h3><p>当我们在 promise 的 Executor 中 抛出异常的话，也是会调用错误捕获的回调函数的</p><p>通过 carch 方法 才传入 错误（拒绝）捕获的回调函数 （不符合 promise/A+ 规范）只是 es6 为了方便才新增的方法</p><div class="language-javascript"><pre><code>Promise<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// 包含两个promise  一个是promise  一个是then 返回的 promise</span>
    <span class="token function">reject</span><span class="token punctuation">(</span><span class="token string">&quot;warn&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span><span class="token string">&quot;error&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token comment">//优先捕获 上一个  promise  如果这个 promise没有抛出异常  会捕获then中返回的promise 的异常错误</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>catch 也是有返回值 的跟 then 一样也会返回 promise</p><h3 id="promise-finally（es8）"><a class="header-anchor" href="#promise-finally（es8）" aria-hidden="true">#</a> promise finally（ES8）</h3><p>无论是错误异常 都会被执行</p><p>不是 Promise A+ 规范</p><div class="language-javascript"><pre><code><span class="token keyword">const</span> promise <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span> reject</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">&quot;6666&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
promise
  <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;res&quot;</span><span class="token punctuation">,</span> res<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">finally</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    j<span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&quot;finaly  code executor&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="promise-类方法"><a class="header-anchor" href="#promise-类方法" aria-hidden="true">#</a> promise 类方法</h3><p><strong>promise.resolve</strong>（obj） 直接把一个对象转化成 promise</p><p><strong>promise.reject</strong>（） 无论传什么都是一样的</p><p><strong>promise.all （</strong>【p1,p2,p3, &#39;aaa&#39;】）等到传入的 promise 都是 resolved 结果 会返回一个数组 如果有一个 promise 变成了 rejected，那么整个 promise 就变成 rejected 状态</p><p><strong>promise.allsettled() es11</strong> 等到所有 promise 的都有结果 无论失败还是成功都会返回一个数组 里面有很多对象 ，对象中会标明每个 promise 的状态</p><p><strong>promise.race（）</strong> 也是传入一个数组 只要一一个 promise 是 fuilled 就结束 如果第一个是拒绝 那么就直接拒绝</p><p><strong>promise.any （）es12</strong> 至少等到一个状态是成功 才返回结果 如果都是拒绝 那么会等到所有的 promise 都结束 会进入 catch</p><h2 id="iterator-迭代器-与-generator-生成器"><a class="header-anchor" href="#iterator-迭代器-与-generator-生成器" aria-hidden="true">#</a> iterator 迭代器 与 generator 生成器</h2><h3 id="迭代器协议："><a class="header-anchor" href="#迭代器协议：" aria-hidden="true">#</a> 迭代器协议：</h3><p>是确使用户可在容器对象（container，链表或数组），上遍历的对象，使用该接口无需关心对象的内部实现细节</p><p>迭代器本身是一个对象，帮助我们对某个数据结构进行遍历的对象</p><ul><li><p>必须符合迭代器协议</p></li><li><p>迭代器协议定义了产生一系列值（无论是有限个还是无线个）的标准方式</p></li><li><p>在 JS 中这个标准就是一个特定的 next 方法</p><p>next 方法的要求：</p><ol><li><p>一个带有一个参数或者没有参数。返回一个应当用有以下两个属性的对象：</p><ul><li><p>done （boolean）</p><ul><li>如果迭代器可以产生序列中的下一个值， 则为 fasle，（等价于没有指定 done 这个属性）</li><li>如果迭代器已将序列迭代完毕，则为 true，这种情况 value 是可选的，如果存在就是迭代器结束只会的默认值</li></ul></li><li><p>value</p><ul><li>迭代器返回的任何 Javascript 值，done 为 true 时可省略</li></ul></li></ul></li></ol></li></ul><div class="language-javascript"><pre><code><span class="token comment">// 数组</span>
<span class="token keyword">const</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">&#39;111&#39;</span><span class="token punctuation">,</span><span class="token string">&#39;222&#39;</span><span class="token punctuation">,</span><span class="token string">&#39;333&#39;</span><span class="token punctuation">]</span>

<span class="token keyword">let</span> index <span class="token operator">=</span> <span class="token number">0</span>
<span class="token comment">// 迭代器对象</span>
<span class="token keyword">const</span> iterator <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token function-variable function">next</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
      <span class="token keyword">if</span><span class="token punctuation">(</span>index<span class="token operator">&lt;=</span>arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token punctuation">{</span>done<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>value<span class="token operator">:</span> arr<span class="token punctuation">[</span>index<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token punctuation">}</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token punctuation">{</span>done<span class="token operator">:</span><span class="token boolean">true</span><span class="token punctuation">,</span>value<span class="token operator">:</span><span class="token keyword">undefined</span> <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token comment">// console.log(iterator.next());     { done: false,value:&#39;111&#39; }</span>
<span class="token comment">// console.log(iterator.next());     { done: false,value:&#39;222&#39; }</span>
<span class="token comment">// console.log(iterator.next());     { done: false,value:&#39;333&#39; }</span>
<span class="token comment">// console.log(iterator.next());     { done: false,value:&#39;undefined&#39; }</span>
··················································································
<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string"> 有限 的迭代器</span><span class="token template-punctuation string">`</span></span>
<span class="token keyword">function</span> <span class="token function">createInterator</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">let</span> index  <span class="token operator">=</span> <span class="token number">0</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span>
    <span class="token function-variable function">next</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
      <span class="token keyword">if</span><span class="token punctuation">(</span>index <span class="token operator">&lt;</span> arr<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token punctuation">{</span> done<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>value<span class="token operator">:</span>arr<span class="token punctuation">[</span>index<span class="token operator">++</span><span class="token punctuation">]</span><span class="token punctuation">}</span>
      <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token punctuation">{</span> done<span class="token operator">:</span><span class="token boolean">true</span> <span class="token punctuation">,</span> value<span class="token operator">:</span><span class="token keyword">undefined</span><span class="token punctuation">}</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">无限的迭代器</span><span class="token template-punctuation string">`</span></span>
但 done 一直为<span class="token boolean">false</span> 就是无限迭代器
</code></pre></div><h3 id="可迭代对象："><a class="header-anchor" href="#可迭代对象：" aria-hidden="true">#</a> 可迭代对象：</h3><ul><li><p>当一个对象实现了 iterable protocol 协议时 ，它就是一个可迭代对象</p></li><li><p>符合可迭代协议， 要有【Symbol。iterator】函数</p></li></ul><div class="language-javascript"><pre><code><span class="token keyword">const</span> iterableObj <span class="token operator">=</span> <span class="token punctuation">{</span>
  names<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">&quot;abc&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;zxc&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;asd&quot;</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">[</span>Symbol<span class="token punctuation">.</span>iterator<span class="token punctuation">]</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">let</span> index <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      <span class="token function-variable function">next</span><span class="token operator">:</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>index <span class="token operator">&lt;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>names<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">{</span>
          <span class="token keyword">return</span> <span class="token punctuation">{</span> done<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span> value<span class="token operator">:</span> <span class="token keyword">this</span><span class="token punctuation">.</span>names<span class="token punctuation">[</span>index<span class="token operator">++</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
          <span class="token keyword">return</span> <span class="token punctuation">{</span> done<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> value<span class="token operator">:</span> <span class="token keyword">undefined</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="原生迭代器对象"><a class="header-anchor" href="#原生迭代器对象" aria-hidden="true">#</a> 原生迭代器对象</h3><ul><li>String，Array，Map，Set，arguments，NodeList 集合</li></ul><h3 id="可迭代对象的应用"><a class="header-anchor" href="#可迭代对象的应用" aria-hidden="true">#</a> 可迭代对象的应用</h3><ul><li>for 。。of 只能遍历可迭代对象 ，就是迭代器 next，拿到 value 赋值给 item 当 done 为 true 才停止遍历</li><li>展开语法， yield</li></ul><p>对于普通对象来说 可以使用展开运算符是 ES9 新增的一个 特性 ，不属于可迭代器的应用</p><h3 id="生成器："><a class="header-anchor" href="#生成器：" aria-hidden="true">#</a> 生成器：</h3><p>一般的函数是不能暂停运行的 return 之后的代码不能执行</p><ul><li>生成器是一个函数，返回的就是生成器</li><li>生成器 要在 function 后面加上一个 *</li><li>生成器函数 通过 yield 控制函数的执行流程</li><li>生成器是一个特殊的迭代器</li></ul><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token operator">*</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;start1&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">yield</span>  value           <span class="token operator">===</span><span class="token operator">===</span>》》  这里  <span class="token keyword">yield</span>  可以跟上 返回值
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;222222&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">yield</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;3333333333&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">yield</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;444444444&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> generator <span class="token operator">=</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

generator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token comment">// start1    返回的是     { done： false， value:undefined}   返回值 作为value</span>
generator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token comment">// 2222222222            { done： false， value:undefined}</span>
generator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token comment">// 333333333333           { done： false， value:undefined}</span>
generator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token comment">//  44444444</span>

</code></pre></div><h3 id="生成器的应用"><a class="header-anchor" href="#生成器的应用" aria-hidden="true">#</a> 生成器的应用</h3><p><strong>上一个 yield 的返回值 作为下一次 next（） 的参数</strong></p><p><strong>生成器来代替迭代器</strong></p><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token operator">*</span> <span class="token function">createIterator</span><span class="token punctuation">(</span><span class="token parameter">arr</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">const</span> item <span class="token keyword">of</span> arr<span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">yield</span> item
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> songs <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">&#39;无条件&#39;</span><span class="token punctuation">,</span> <span class="token string">&#39;shall we talk&#39;</span><span class="token punctuation">,</span> <span class="token string">&#39;1874&#39;</span><span class="token punctuation">]</span>

<span class="token keyword">const</span> songsIterator <span class="token operator">=</span> <span class="token function">createIterator</span><span class="token punctuation">(</span>songs<span class="token punctuation">)</span>


console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>songsIterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>songsIterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>songsIterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>songsIterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


<span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token string">&#39;无条件&#39;</span><span class="token punctuation">,</span> done<span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span>
<span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token string">&#39;shall we talk&#39;</span><span class="token punctuation">,</span> done<span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span>
<span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token string">&#39;1874&#39;</span><span class="token punctuation">,</span> done<span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span>
<span class="token punctuation">{</span> value<span class="token operator">:</span> <span class="token keyword">undefined</span><span class="token punctuation">,</span> done<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span>
</code></pre></div><p><strong>yield * 语法</strong> 必须跟上一个可迭代对象 会自动返回 可迭代对象</p><p>可以处理异步函数</p><h2 id="async-await"><a class="header-anchor" href="#async-await" aria-hidden="true">#</a> async/await</h2><h3 id="async-异步-关键字-声明一个函数为异步函数"><a class="header-anchor" href="#async-异步-关键字-声明一个函数为异步函数" aria-hidden="true">#</a> async 异步 关键字 声明一个函数为异步函数</h3><p>sync 同步</p><div class="language-javascript"><pre><code><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

<span class="token keyword">const</span> <span class="token function-variable function">foo1</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">Foo</span> <span class="token punctuation">{</span>
  <span class="token keyword">async</span> <span class="token function">bar</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p><strong>异步函数 如果不加特殊代码的情况下，跟普通函数没区别</strong></p><p>和普通函数的区别</p><ol><li>返回值：异步函数的返回值一定是个 promise</li><li>异步错误的异常 会作为 返回的 promise 的 reject 的值 需要被 catch 捕获</li></ol><h3 id="await"><a class="header-anchor" href="#await" aria-hidden="true">#</a> await</h3><p>只能用在异步函数中 ，一般跟着表达式 并且返回一个 promise</p><div class="language-javascript"><pre><code><span class="token keyword">function</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">resolve<span class="token punctuation">,</span>reject</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
    <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span>
      <span class="token function">resolve</span><span class="token punctuation">(</span><span class="token string">&#39;33333&#39;</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">5000</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>


<span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  consr res <span class="token operator">=</span>   <span class="token keyword">await</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#39;~~~~~~~~~~~~~~~~~~&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// await 后面的代码相当于 await 返回的 promise的then(()=&gt;{})的方法执行</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span> <span class="token string">&#39;执行&#39;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment">//</span>
<span class="token punctuation">}</span>

<span class="token function">foo</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><h2 id="js-模块化"><a class="header-anchor" href="#js-模块化" aria-hidden="true">#</a> JS 模块化</h2><h3 id="commonjs"><a class="header-anchor" href="#commonjs" aria-hidden="true">#</a> CommonJS</h3><ul><li>Node 是 CommonJS 在服务端一个具有代表性的实现</li><li>Browserify 是 CommonJS 在浏览器中的一种实现</li><li>webpack 打包工具具备对 CommonJS 的支持和转化</li></ul><p><strong>Node</strong></p><ol><li>在 Node 中 每一个 JS 文件都是一个单独的模块</li><li>这个模块中包括 CommonJS 规范的核心变量： exports， module.exports， require</li><li>我们可以使用这些变量方便的进行模块化开发</li></ol><p><strong>模块化的核心就是导入和导出</strong></p><ul><li>exports 和 module.exprts 可以负责对模块中的内容进行导出</li><li>requier 函数可以帮助我们导入其他模块（自定义模块。系统模块。第三方库模块）中 的内容</li></ul><h3 id="导出方案："><a class="header-anchor" href="#导出方案：" aria-hidden="true">#</a> 导出方案：</h3><ol><li><p>module.exports 是一个对象。 module 是当前文件本身的模块对象，其中有一个 exports 属性，这个属性也是一个对象，放入这个对象中的属性都会被导出</p><div class="language-javascript"><pre><code>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
  name<span class="token operator">:</span> <span class="token string">&quot;easom&quot;</span><span class="token punctuation">,</span>
  songs<span class="token operator">:</span> <span class="token number">1874</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div></li><li><p><a href="http://exports.xxx" target="_blank" rel="noopener noreferrer">exports.xxx</a> = xxx 导出</p></li><li></li></ol><h3 id="导入方案："><a class="header-anchor" href="#导入方案：" aria-hidden="true">#</a> 导入方案：</h3><ol><li>通过 require 函数 导入 后面跟上一个路径 可以不写文件后缀也可以不写，会返回一个对象，这个对象就是导出的对象</li></ol><div class="language-javascript"><pre><code><span class="token keyword">const</span> <span class="token punctuation">{</span> name<span class="token punctuation">,</span> songs <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">&quot;./test.js&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><strong>查找规则</strong> require（X）</p><ol><li>X 是一个 Node 核心模块，比如 path，http ，直接返回核心模块。停止查找</li><li>X 是一个路径 ../ ./ <ul><li>将 X 当作一个文件在对应目录下查找</li><li>如果没有后缀名 <ol><li>直接查找文件 X</li><li>查找 X.js 文件</li><li>查找 X.json 文件</li><li>查找 X.node 文件</li></ol></li><li>当没有找到对应的文件， 将 X 作为一个目录 <ol><li>查找 X/index,js 文件</li><li>查找 X/index,json 文件</li><li>查找 X/index.node.文件</li></ol></li></ul></li><li>X 不是核心模块也不是 文件 <ul><li>会沿着当前目录 的 nodeMudules 的文件夹 一层一层的往上查找</li></ul></li></ol><h3 id="内部原理："><a class="header-anchor" href="#内部原理：" aria-hidden="true">#</a> 内部原理：</h3><p>导出的对象，以及导入的对象，其实都是 对象本身的引用 ，三个对象都是相等的，三个引用赋值</p><p>因为在源码中 : 导出的 只能是 module.exports 是为了符合 commonJs 规范</p><div class="language-apl"><pre><code>module<span class="token dyadic-operator operator">.</span>exports <span class="token function">=</span> <span class="token dfn builtin">{</span><span class="token dfn builtin">}</span>
exports <span class="token function">=</span> module<span class="token dyadic-operator operator">.</span>exports
</code></pre></div><p>当 exports 跟 module.exports 引用的不是同一个对象的话 ，最终以 module。exports 导出的对象为准</p><p>每一个 JS 文件都有一个 Module 实例》》有着 loaded 属性 记录着当前模块有没有被加载过 true 代表已经加载过</p><h3 id="模块的加载过程："><a class="header-anchor" href="#模块的加载过程：" aria-hidden="true">#</a> 模块的加载过程：</h3><ul><li>模块在被第一次引入时，模块中的 JS 代码会被运行一次</li><li>模块多次引用时，代码只会被运行一次，会被缓存</li></ul><p>循环引用的加载顺序 <img src="/interview/assets/模块的加载顺序.c7366f85.png" style="zoom:80%;"></p><ul><li>是一种数据结构 图结构</li><li>图结构在遍历的过程中，有深度优先搜索（DFS）,和广度优先搜索</li><li>Node 采用的是深度优先搜索算法： main 》》aaa》》》ccc》》》ddd》》》eee》》》bbb</li></ul><h3 id="缺点："><a class="header-anchor" href="#缺点：" aria-hidden="true">#</a> 缺点：</h3><p>因为模块的加载是运行时的，是同步的加载，只有等到对应模块加载</p><h3 id="es-module"><a class="header-anchor" href="#es-module" aria-hidden="true">#</a> ES Module</h3><ul><li>采用 <strong>import</strong> 和 <strong>export</strong>关键字</li><li>采用编译期的静态分析， 并且也加入了动态引入的方式</li></ul><p>自动采用严格模式</p><p>在 script 标签需要加上 type=module</p><div class="language-html"><pre><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>./main.js<span class="token punctuation">&quot;</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>module<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>live-server 打开：开启一个本地服务器，返回的资源</p><p>协议的前缀 不能有 file 前缀 支持 http 和 https 需要通过一个服务器来测试</p><h3 id="导出的方式：-具名导出"><a class="header-anchor" href="#导出的方式：-具名导出" aria-hidden="true">#</a> 导出的方式： 具名导出</h3><ol><li>export const name = &#39;tzw&#39; export 跟上声明语句</li><li>export { name } 不是一个对象，是一个语法， 放入标识符就可以</li><li>export { name as fName } 用 as 关键字起别名</li></ol><h3 id="导入的方式："><a class="header-anchor" href="#导入的方式：" aria-hidden="true">#</a> 导入的方式：</h3><ol><li>import { name } from &#39;./test.js&#39; 正常导入</li><li>import { name as fName } from &#39;./test.js&#39; 通过 as 关键字 取别名</li><li>import _ as foo from &#39;./test.js&#39; 通过 _ 通配符放到 foo 标识符中</li></ol><h3 id="导入导出结合使用："><a class="header-anchor" href="#导入导出结合使用：" aria-hidden="true">#</a> 导入导出结合使用：</h3><p>在文件夹中 用 index.js 进行统一的导入和导出</p><div class="language-javascript"><pre><code><span class="token comment">//  index.js</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> add<span class="token punctuation">,</span> sum <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./math.js&quot;</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> timeFormat <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;./day.js&quot;</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token punctuation">{</span> add<span class="token punctuation">,</span> sum<span class="token punctuation">,</span> timeFormat <span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token operator">*</span> <span class="token keyword">from</span> <span class="token string">&quot;./math.js&quot;</span><span class="token punctuation">;</span> <span class="token comment">//  导出所有</span>
<span class="token keyword">export</span> <span class="token keyword">default</span> add<span class="token punctuation">;</span> <span class="token comment">//  最重要的东西可以采用默认导出</span>
</code></pre></div><h3 id="默认导出："><a class="header-anchor" href="#默认导出：" aria-hidden="true">#</a> 默认导出：</h3><p><strong>default</strong> 关键字 作为 默认导出 默认导出只有一个</p><h3 id="import-异步加载-函数"><a class="header-anchor" href="#import-异步加载-函数" aria-hidden="true">#</a> import 异步加载 函数</h3><p>import（‘./&#39;foo.js）.then (res+&gt;{}) import 函数返回的是一个 promise 内部会调用 resolve（）</p><p>必须等 import 函数导入 完成 才能继续执行下面的代码</p><h3 id="import-meta-属性："><a class="header-anchor" href="#import-meta-属性：" aria-hidden="true">#</a> import.<wbr>meta 属性：</h3><p>包含 url 属性 包含当前模块的路径</p><h3 id="es-module-的解析流程："><a class="header-anchor" href="#es-module-的解析流程：" aria-hidden="true">#</a> ES module 的解析流程：</h3><p>ES Module 的解析过程可以划分为三个阶段：</p><ul><li><strong>构建，根据地址查找 JS 文件，并且下载，将其解析成模块记录 Module Record</strong><img src="/interview/assets/ESmodule构建阶段.4bece6de.png" style="zoom:80%;"></li><li>实例化，对模块记录进行实例化，并且分配内存空间，解析模块的导入和导出语句，把模块指向对应的内存地址</li><li>运行 运行代码，计算值，并且将值填充到内存地址中</li></ul><img src="/interview/assets/ESmodule实例化求值阶段.d7c33810.png" style="zoom:80%;"><h1 id="eventloop-浏览器"><a class="header-anchor" href="#eventloop-浏览器" aria-hidden="true">#</a> EventLoop-浏览器</h1><h2 id="进程-与线程"><a class="header-anchor" href="#进程-与线程" aria-hidden="true">#</a> 进程 与线程</h2><ul><li>进程（process）： 计算机已经运行的程序，启动一个应用程序就是一个进程</li><li>线程（thread）： 操作系统能够运行运算调度的最小单位，一般被包含在进程中</li></ul><p><strong>JS 单线程</strong></p><p>js 线程应该有自己的容器进程：浏览器或者 node，js 同一时刻只能做一件事，如果非常耗时，当前的线程就会被阻塞</p><p>浏览器每开启一个 tab 就会开启一个进程。 一个进程中会有很多线程，</p><p>真正耗时的 操作 不是由 js 线程执行。是通过浏览器的其他线程完成这些耗时的操作，并进行回调</p><h2 id="事件循环-事件队列"><a class="header-anchor" href="#事件循环-事件队列" aria-hidden="true">#</a> 事件循环/ 事件队列</h2><p>浏览器维护了一个队列 Queue 是一种线性数据结构，一种特殊的数组，先进先出</p><p>js 线程——》其他线程——》事件队列——》js 线程 这一个闭环就属于事件循环</p><p>js 引擎发起耗时操作，》》提交给其他线程》》加入浏览器的队列中》》交给 js 引擎继续执行</p><img src="/interview/assets/事件循环.105fab99.png" style="zoom:80%;"><h2 id="宏任务队列-macrotask"><a class="header-anchor" href="#宏任务队列-macrotask" aria-hidden="true">#</a> 宏任务队列(MacroTask)</h2><p><strong>在执行任何 宏任务之前 都要清空 微任务队列</strong></p><ol><li>定时器： setimeout， setInterval</li><li>ajax 请求</li><li>DOM 操作</li><li>UI 渲染</li></ol><h2 id="微任务队列-microtask"><a class="header-anchor" href="#微任务队列-microtask" aria-hidden="true">#</a> 微任务队列(MicroTask)</h2><ol><li>queueMicrotak</li><li>promise.then</li></ol><h2 id="队列任务执行优先级"><a class="header-anchor" href="#队列任务执行优先级" aria-hidden="true">#</a> 队列任务执行优先级</h2><ul><li>main script 中的代码优先执行 （编写顶层的 script 代码）</li><li>执行任何一个宏任务之前（不是队列，是一个微任务），都会查看微任务队列中 是否有任务需要执行 <ol><li>也就是宏任务执行前，必须保证微任务队列是空的</li><li>如果不为空。那么优先执行微任务队列中 的任务（回调）</li></ol></li></ul><h2 id="js-中的高阶函数"><a class="header-anchor" href="#js-中的高阶函数" aria-hidden="true">#</a> JS 中的高阶函数</h2><h3 id="_1-map"><a class="header-anchor" href="#_1-map" aria-hidden="true">#</a> 1.map</h3><ul><li><code>map()</code>返回一个新的数组，数组中的元素为原始数组调用函数处理后的值。</li><li><code>map()</code>不会对空数组进行检测。</li><li><code>map()</code>不会改变原始数组。</li></ul><p>传递给 <code>map()</code> 方法的回调函数接受 <strong>3</strong> 个参数：<code>currentValue</code>，<code>index</code> 和 <code>array</code>。</p><ol><li><code>currentValue</code>：<strong>必须</strong>。当前元素的的值。</li><li><code>index</code>：<strong>可选</strong>。当前元素的索引。</li><li><code>arr</code>：<strong>可选</strong>。当前元素属于的数组对象。</li></ol><p>有这样一个数组 <code>[10,20,45,50,65,150,70,40]</code> 现在有如下需求</p><p>把数组中所有的元素 * <strong>2</strong>。</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">45</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">,</span> <span class="token number">65</span><span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">,</span> <span class="token number">70</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> newArr <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> item <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>newArr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [20, 40, 90, 100, 130, 300, 140, 80]</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><h3 id="_2-filter"><a class="header-anchor" href="#_2-filter" aria-hidden="true">#</a> 2.filter</h3><ul><li><code>filter()</code>方法创建一个新的数组，新数组中的元素是通过检查指定数组中符合条件的所有元素。</li><li><code>filter()</code>不会对空数组进行检测。</li><li><code>filter()</code>不会改变原始数组。</li></ul><p>传递给 <code>filter()</code> 方法的回调函数接受 <strong>3</strong> 个参数：<code>currentValue</code>，<code>index</code> 和 <code>array</code>。</p><ol><li><code>currentValue</code>：<strong>必须</strong>。当前元素的的值。</li><li><code>index</code>：<strong>可选</strong>。当前元素的索引。</li><li><code>arr</code>：<strong>可选</strong>。当前元素属于的数组对象。</li></ol><p>有这样一个数组<code> [20, 40, 90, 100, 130, 300, 140, 80]</code> 现在有如下需求</p><p>返回数组中所有小于 <strong>100</strong> 的元素。</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">90</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">130</span><span class="token punctuation">,</span> <span class="token number">300</span><span class="token punctuation">,</span> <span class="token number">140</span><span class="token punctuation">,</span> <span class="token number">80</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> newArr <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> item <span class="token operator">&lt;</span> <span class="token number">100</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>newArr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//[20, 40, 90, 80]</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><h3 id="_3-foreach"><a class="header-anchor" href="#_3-foreach" aria-hidden="true">#</a> 3.forEach</h3><ul><li><code>forEach()</code>方法类似于 <code>map()</code>，传入的函数不需要返回值,并将元素传递给回调函数。</li><li><code>forEach()</code> 对于空数组是不会执行回调函数的。</li><li><code>forEach()</code>不会返回新的数组,总是返回 undefined.</li></ul><p>传递给 <code>forEach()</code> 方法的回调函数接受 <strong>3</strong> 个参数：<code>currentValue</code>，<code>index</code> 和 <code>array</code>。</p><ol><li><code>currentValue</code>：<strong>必须</strong>。当前元素的的值。</li><li><code>index</code>：<strong>可选</strong>。当前元素的索引。</li><li><code>arr</code>：<strong>可选</strong>。当前元素属于的数组对象。</li></ol><p>有这样一个数组 <code>[20, 40, 90, 100]</code> 现在有如下需求。</p><p>分别打印数组中的元素及其索引。</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">,</span> <span class="token number">90</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> newArr <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item<span class="token punctuation">,</span> index</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>item<span class="token punctuation">,</span> index<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//20 0</span>
<span class="token comment">//40 1</span>
<span class="token comment">//90 2</span>
<span class="token comment">//100 3</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><h3 id="_4-sort"><a class="header-anchor" href="#_4-sort" aria-hidden="true">#</a> 4.sort</h3><ul><li><code>sort()</code>方法用于对数组的元素进行排序。</li><li><code>sort()</code>会修改原数组。</li></ul><p><code>sort()</code> 方法接受一个可选参数,用来规定排序顺序,必须是函数。</p><p>如果没有传递参数, <code>sort()</code> 方法默认把所有元素先转换为 <code>String</code> 再排序 ,根据 <code>ASCII</code> 码进行排序。</p><p>如果想按照其他标准进行排序，就需要提供比较函数，该函数要比较两个值，然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 <strong>a</strong> 和 <strong>b</strong>，其返回值如下：</p><ul><li>若 <code>a</code> 小于 <code>b</code>，在排序后的数组中 <code>a</code> 应该出现在 <code>b</code> 之前，则返回一个小于 <code>0</code> 的值。</li><li>若 <code>a</code> 等于 <code>b</code>，则返回 <code>0</code>。</li><li>若 <code>a</code> 大于 <code>b</code>，则返回一个大于 <code>0</code> 的值。</li></ul><p>有这样一个数组 <code>[10, 20, 1, 2]</code> 现在有如下需求</p><p>按从小到大排序。</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">&lt;</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">&gt;</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [1, 2, 10, 20]</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><p>按从大到小排序</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
arr<span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">x<span class="token punctuation">,</span> y</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">&lt;</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token operator">&gt;</span> y<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// [20, 10, 2, 1]</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><h3 id="_5-some"><a class="header-anchor" href="#_5-some" aria-hidden="true">#</a> 5.some</h3><ul><li><code>some()</code> 方法用于检测数组中的元素是否满足指定条件。</li><li><code>some()</code> 方法会依次执行数组的每个元素。</li><li>如果有一个元素满足条件，则表达式返回 <code>true</code>, 剩余的元素不会再执行检测。</li><li>如果没有满足条件的元素，则返回 <code>false</code> 。</li><li><code>some()</code>不会对空数组进行检测。</li><li><code>some()</code>不会改变原始数组。</li></ul><p>传递给 <code>some() </code>方法的回调函数接受 <strong>3</strong> 个参数：<code>currentValue</code>，<code>index</code> 和 <code>array</code>。</p><ol><li><code>currentValue</code>：<strong>必须</strong>。当前元素的的值。</li><li><code>index</code>：<strong>可选</strong>。当前元素的索引。</li><li><code>arr</code>：<strong>可选</strong>。当前元素属于的数组对象。</li></ol><p>有这样一个数组 <code>[10, 20, 1, 2]</code> 现在有如下需求。</p><p>判断数组中是否含有大于 <strong>10</strong> 的数字。</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> result <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">some</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> item <span class="token operator">&gt;</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//true</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><h3 id="_6-every"><a class="header-anchor" href="#_6-every" aria-hidden="true">#</a> 6.every</h3><ul><li><code>every()</code> 方法用于检测数组所有元素是否都符合指定条件。</li><li><code>every()</code> 方法会依次执行数组的每个元素。</li><li>如果数组中检测到有一个元素不满足，则整个表达式返回 <code>false</code> ，且剩余的元素不会再进行检测。</li><li>如果所有元素都满足条件，则返回 <code>true</code>。</li><li><code>every()</code>不会对空数组进行检测。</li><li><code>every()</code>不会改变原始数组。</li></ul><p>传递给 <code>every()</code> 方法的回调函数接受 <strong>3</strong> 个参数：<code>currentValue</code>，<code>index</code> 和 <code>array</code>。</p><ol><li><code>currentValue</code>：<strong>必须</strong>。当前元素的的值。</li><li><code>index</code>：<strong>可选</strong>。当前元素的索引。</li><li><code>arr</code>：<strong>可选</strong>。当前元素属于的数组对象。</li></ol><p>有这样一个数组 <code>[11, 20, 51, 82]</code> 现在有如下需求。</p><p>判断数组中是否所有的数字都大于 <code>10</code>。</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">11</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">51</span><span class="token punctuation">,</span> <span class="token number">82</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> result <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">every</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> item <span class="token operator">&gt;</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//true</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><h3 id="_7-reduce"><a class="header-anchor" href="#_7-reduce" aria-hidden="true">#</a> 7.reduce</h3><ul><li><code>reduce()</code> 方法接收一个函数作为累加器，数组中的每个值（从左到右）开始缩减，最终计算为一个值。</li><li><code>reduce()</code>对于空数组是不会执行回调函数的。</li></ul><p><code>reduce</code> 方法接收两个参数</p><ul><li>回调函数</li><li>一个可选的 <code>initialValue</code> (初始值)。如果不传第二个参数 <code>initialValue</code>，则函数的第一次执行会将数组中的第一个元素作为 <code>prev</code> 参数返回。</li></ul><p>传递给 <code>reduce()</code> 方法的回调函数接受 <strong>4</strong> 个参数：<code>prev</code>, <code>current</code>, <code>currentIndex</code>, <code>arr</code>。</p><ol><li><code>prev</code>：<strong>必须</strong>。函数传进来的初始值或上一次回调的返回值。</li><li><code>current</code>：<strong>必须</strong>。数组中当前处理的元素值。</li><li><code>currentIndex</code>：<strong>可选</strong>。当前元素索引。</li><li><code>arr</code>：<strong>可选</strong>。当前元素所属的数组本身。</li></ol><p>有这样一个数组<code>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</code> 现在有如下需求</p><p>返回数组所有元素累加之和</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">,</span> <span class="token number">9</span><span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> sum <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">prev<span class="token punctuation">,</span> current</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> prev <span class="token operator">+</span> current<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>sum<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//55</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><h3 id="_8-reduceright"><a class="header-anchor" href="#_8-reduceright" aria-hidden="true">#</a> 8.reduceRight</h3><p><code>reduceRight()</code> 方法的功能和 <code>reduce()</code> 功能是一样的，不同的是 <code>reduceRight()</code> 从数组的末尾向前将数组中的数组项做累加。</p><h3 id="_9-find"><a class="header-anchor" href="#_9-find" aria-hidden="true">#</a> 9.find</h3><ul><li><code>find()</code>方法用于查找符合条件的第一个元素，如果找到了，返回这个元素，否则，返回<code>undefined</code>。</li><li><code>find()</code>不会对空数组进行检测。</li><li><code>find()</code>不会改变原始数组。</li></ul><p>传递给 <code>find()</code> 方法的回调函数接受 <strong>3</strong> 个参数：<code>currentValue</code>，<code>index</code> 和 <code>array</code>。</p><ol><li><code>currentValue</code>：<strong>必须</strong>。当前元素的的值。</li><li><code>index</code>：<strong>可选</strong>。当前元素的索引。</li><li><code>arr</code>：<strong>可选</strong>。当前元素属于的数组对象。</li></ol><p>有这样一个数组 <code>[11, 20, 51, 82]</code> 现在有如下需求</p><p>返回数组中第一个大于 50 的元素</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">11</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">51</span><span class="token punctuation">,</span> <span class="token number">82</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> result <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> item <span class="token operator">&gt;</span> <span class="token number">50</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//51</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><h3 id="_10-findindex"><a class="header-anchor" href="#_10-findindex" aria-hidden="true">#</a> 10.findIndex</h3><p><code>findindex()</code> 和 <code>find()</code> 类似，也是查找符合条件的第一个元素，不同之处在于 <code>findindex()</code> 会返回这个元素的索引，如果没有找到，返回 <code>-1</code> 。</p><p>有这样一个数组 <code>[11, 20, 51, 82]</code> 现在有如下需求。</p><p>返回数组中第一个大于 <strong>50</strong> 的元素索引。</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">11</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">51</span><span class="token punctuation">,</span> <span class="token number">82</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> result <span class="token operator">=</span> arr<span class="token punctuation">.</span><span class="token function">findIndex</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> item <span class="token operator">&gt;</span> <span class="token number">50</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// 2</span>
复制代码<span class="token punctuation">;</span>
</code></pre></div><h3 id="链式调用高阶函数"><a class="header-anchor" href="#链式调用高阶函数" aria-hidden="true">#</a> 链式调用高阶函数</h3><p>假如有一个数组 <code>[10, 20, 45, 50, 65, 150, 70, 40]</code></p><p>需求一:给数组中的每个元素 <code>* 2</code></p><p>我们使用的是 <code>map()</code> ,得到了<code>[20, 40, 90, 100, 130, 300, 140, 80]</code></p><p>需求二:返回需求一中得到的新数组所有小于 <strong>100</strong> 的元素</p><p>我们使用的是<code>filter()</code> , 得到了<code>[20, 40, 90, 80]</code></p><p>需求三:计算需求二中得到的新数组所有元素之和</p><p>我们使用的是<code>reduce()</code>,得到了 <strong>230</strong></p><p>我们可以链式调用上述三个函数,来得到最终的结果</p><div class="language-js"><pre><code><span class="token keyword">let</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">45</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">,</span> <span class="token number">65</span><span class="token punctuation">,</span> <span class="token number">150</span><span class="token punctuation">,</span> <span class="token number">70</span><span class="token punctuation">,</span> <span class="token number">40</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> total <span class="token operator">=</span> arr
  <span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> n <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> n <span class="token operator">&lt;</span> <span class="token number">100</span><span class="token punctuation">)</span>
  <span class="token punctuation">.</span><span class="token function">reduce</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">pre<span class="token punctuation">,</span> n</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> pre <span class="token operator">+</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>total<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//230</span>
</code></pre></div></div></div><footer class="page-footer" data-v-7eddb2c4 data-v-fb8d84c6><div class="edit" data-v-fb8d84c6><div class="edit-link" data-v-fb8d84c6 data-v-1ed99556><!----></div></div><div class="updated" data-v-fb8d84c6><!----></div></footer><div class="next-and-prev-link" data-v-7eddb2c4 data-v-38ede35f><div class="container" data-v-38ede35f><div class="prev" data-v-38ede35f><a class="link" href="/interview/WebPack/advanced" data-v-38ede35f><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon icon-prev" data-v-38ede35f><path d="M19,11H7.4l5.3-5.3c0.4-0.4,0.4-1,0-1.4s-1-0.4-1.4,0l-7,7c-0.1,0.1-0.2,0.2-0.2,0.3c-0.1,0.2-0.1,0.5,0,0.8c0.1,0.1,0.1,0.2,0.2,0.3l7,7c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3c0.4-0.4,0.4-1,0-1.4L7.4,13H19c0.6,0,1-0.4,1-1S19.6,11,19,11z"></path></svg><span class="text" data-v-38ede35f>手写简单的MY_Webpack</span></a></div><div class="next" data-v-38ede35f><a class="link" href="/interview/Javascript/advanced" data-v-38ede35f><span class="text" data-v-38ede35f>高级语法</span><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24" class="icon icon-next" data-v-38ede35f><path d="M19.9,12.4c0.1-0.2,0.1-0.5,0-0.8c-0.1-0.1-0.1-0.2-0.2-0.3l-7-7c-0.4-0.4-1-0.4-1.4,0s-0.4,1,0,1.4l5.3,5.3H5c-0.6,0-1,0.4-1,1s0.4,1,1,1h11.6l-5.3,5.3c-0.4,0.4-0.4,1,0,1.4c0.2,0.2,0.5,0.3,0.7,0.3s0.5-0.1,0.7-0.3l7-7C19.8,12.6,19.9,12.5,19.9,12.4z"></path></svg></a></div></div></div><!--[--><!--]--></div></main></div><!----><!--]--></div>
    <script>__VP_HASH_MAP__ = JSON.parse("{\"index.md\":\"992e2bc4\",\"css_advanced.md\":\"157298f3\",\"css_index.md\":\"0df1ef28\",\"browser_advanced.md\":\"a7a79457\",\"browser_index.md\":\"9938c247\",\"browser_plugin.md\":\"fd27046d\",\"git_index.md\":\"fb33a92a\",\"html_advanced.md\":\"599ad3d5\",\"html_index.md\":\"c94736b6\",\"interview_index.md\":\"07dc8acc\",\"interview_two.md\":\"0ca812f6\",\"javascript_advanced.md\":\"5c434e6d\",\"javascript_index.md\":\"d996a3fc\",\"jenkins_index.md\":\"3068e232\",\"myself_index.md\":\"340fc837\",\"myself_one.md\":\"31202d59\",\"myself_pre.md\":\"aa93248e\",\"network_index.md\":\"7251e8b9\",\"network_security.md\":\"d11dae3c\",\"node_index.md\":\"e0b22fc7\",\"node_pit.md\":\"a1502c64\",\"npm_index.md\":\"59b033b6\",\"pit_index.md\":\"603d46aa\",\"solution_index.md\":\"987aa705\",\"typescript_advanced.md\":\"431b8bba\",\"typescript_combat.md\":\"60c9a8a2\",\"typescript_index.md\":\"bd88b5a2\",\"vite_index.md\":\"d6838c03\",\"vite_optimize.md\":\"49f1bb24\",\"vue_index.md\":\"380ec221\",\"vue_reactive.md\":\"206c8e46\",\"vue_router.md\":\"0d556c25\",\"vue_source.md\":\"592e192a\",\"vue_vuex.md\":\"032502ef\",\"webpack_advanced.md\":\"ae6c63b7\",\"webpack_common.md\":\"141deb7a\",\"webpack_custom.md\":\"4827ebf8\",\"webpack_index.md\":\"49f185a6\",\"webpack_optimize.md\":\"545698f9\",\"vue_source_index.md\":\"1c12bc29\",\"vue_source_nexttick.md\":\"4533a28b\",\"vue_source_watch.md\":\"0e7342fc\"}")</script>
    <script type="module" async src="/interview/assets/app.49accf37.js"></script>
  </body>
</html>